<template>
  <div class="v-merge-property-list g-fs-14">
    <div class="_tool-bar g-h-28 _box-shadow">
      <el-icon
        class="g-pointer g-m-t-6"
        :color="showModified ? '#409eff' : 'black'"
        @click="showModified = !showModified"
      >
        <Filter />
      </el-icon>
      <span class="_type-selector g-m-t-6">
        <MDropdown trigger="click">
          <span class="_tool-btn g-pointer">
            <span class="g-m-r-4">{{ $t(getLevelName(showLevel)) }}</span>
            <img src="statics/header/icontriangle.svg" />
          </span>
          <template #dropdown>
            <MDropdownMenuItem
              v-for="item in showLevelOptions"
              :key="item.value"
              @click="showLevel = item.value"
            >
              {{ $t(item.label) }}
            </MDropdownMenuItem>
          </template>
        </MDropdown>
      </span>
    </div>
    <el-row class="_head g-lh-28 g-bolder">
      <div class="_box-span"></div>
      <el-col
        :span="5"
        class="_box-shadow"
      >
        {{ $t("属性名") }}
      </el-col>
      <el-col
        :span="6"
        class="_box-shadow"
      >
        {{ $t("合并项目") }}
      </el-col>
      <el-col
        :span="6"
        class="_box-shadow"
      >
        {{ $t("当前项目") }}
      </el-col>
      <el-col
        :span="6"
        class="_box-shadow"
      >
        {{ $t("合并结果预览") }}
      </el-col>
    </el-row>
    <el-row
      v-for="property in filteredPropertyList"
      :key="property.propertyId"
      @click="handleSelect(property)"
      @contextmenu="e => handleContextMenu(property, e)"
    >
      <div class="g-flex-center _box-span">
        <img
          v-show="property.propertyId == currentKey"
          src="statics/icons/app/arrowchoose.svg"
        />
      </div>

      <el-col
        :span="5"
        class="_box-shadow g-ai-c"
        :class="{ _selected: property.propertyId == currentKey }"
      >
        {{ $t(property.name) }}
      </el-col>

      <el-col
        :span="6"
        class="_box-shadow _property-row"
      >
        <merge-property-label
          v-for="item in property.sourcePropertyValue"
          :key="item.uid"
          :property-item="item"
        ></merge-property-label>
      </el-col>

      <el-col
        :span="6"
        class="_box-shadow _property-row"
      >
        <merge-property-label
          v-for="item in property.targetPropertyValue"
          :key="item.uid"
          :property-item="item"
        ></merge-property-label>
      </el-col>

      <el-col
        :span="6"
        class="_box-shadow _property-row"
      >
        <merge-property-label
          v-for="item in property.resultPropertyValue"
          :key="item.uid"
          :property-item="item"
        ></merge-property-label>
      </el-col>
    </el-row>
  </div>
</template>

<script lang="ts" setup>
import { computed, inject, ref, watch } from "vue";
import MergePropertyLabel from "./MergePropertyLabel.vue";
import { contextPropertyMenuItem, contextMenuItem, MergeProperty } from "../config";
import ContextMenu from "@/common/ContextMenu/index.vue";
import { projectService } from "@/modules/model/service";
import MDropdown from "@/common/dropdown/Dropdown.vue";
import MDropdownMenuItem from "@/common/dropdown/DropdownMenuItem.vue";
import { Filter } from "@element-plus/icons";
import { Status } from "./logic";
import { ModelMergeInfo } from "@/constants/types";

const targetProjectId = inject("targetProjectId") as string;
const sourceProjectId = inject("sourceProjectId") as string;

const props = defineProps<{
  propertyList: Array<MergeProperty>;
  currentKey: string;
  instanceId: string;
  isDisabled?: boolean;
}>();
const showLevel = ref(3);
const showModified = ref(true);
const filteredPropertyList = computed(() => {
  const result = props.propertyList.filter(it => it.displayLevel <= showLevel.value);
  if (!showModified.value) {
    return result;
  } else {
    return result.filter(it => it.sourcePropertyValue.find(val => val.state !== Status.UNMODIFIED));
  }
});

// 监听变化，为了让属性列表里面点击拒绝接收之后toolbar的菜单随之改变
watch(
  () => [props.propertyList, props.currentKey],
  () => {
    if (props.currentKey) {
      const property = props.propertyList.find(it => it.propertyId === props.currentKey);
      property && handleSelect(property);
    }
  }
);

const emits = defineEmits<{
  (event: "update:currentKey", value: string): void;
  (event: "update:property", modifyModels: string[]): void;
  (event: "updateButtonList", menuConfig: { [key: string]: boolean }): void;
}>();

function handleSelect(row: MergeProperty) {
  emits("update:currentKey", row.propertyId);
  const menu = configMenu(row);
  const menuConfig = {};
  contextMenuItem.forEach(it => {
    if (it.group !== 1) {
      menuConfig[it.key] = true;
    } else {
      menuConfig[it.key] = it.key === "accept" ? menu[0].disabled : menu[1].disabled;
    }
  });
  if (!props.isDisabled) {
    emits("updateButtonList", menuConfig);
  }
}

async function handleContextMenu(property: MergeProperty, event: MouseEvent) {
  if (props.isDisabled) return;
  handleSelect(property);
  const menu = configMenu(property);
  if (menu[0].disabled && menu[1].disabled) {
    return;
  }
  ContextMenu.popup({
    x: event.clientX,
    y: event.clientY,
    menuItems: menu,
    modelId: property.propertyId
  })
    .then(async (menuItem: any) => {
      const dto = {
        targetProjectId,
        sourceProjectId,
        propertyId: property.propertyId,
        instanceId: props.instanceId,
        acceptOperation: menuItem.value,
        value: null
      };
      const mergeInfo = {
        instanceId: props.instanceId
      };
      const data = await projectService.projectMergeUpdateProperty(
        dto.targetProjectId,
        dto.sourceProjectId,
        dto.propertyId,
        dto.acceptOperation,
        [mergeInfo] as ModelMergeInfo[],
        dto.value
      );
      const instanceIds = data.data.modifyModel as string[];
      emits("update:property", instanceIds);
    })
    .catch((e: any) => {
      e && console.error(e);
    });
}

function configMenu(property: MergeProperty) {
  const menu = JSON.parse(JSON.stringify(contextPropertyMenuItem));
  const unmodifiedProperty = property.sourcePropertyValue.filter(it => it.state !== "UNMODIFIED");
  // 如果属性都没有变更，则没有拒绝接收操作
  if (unmodifiedProperty.length === 0) {
    menu[0].disabled = true;
    menu[1].disabled = true;
    return menu;
  }
  if (unmodifiedProperty.every(it => it.accept)) {
    menu[0].disabled = true;
  } else if (unmodifiedProperty.every(it => !it.accept)) {
    menu[1].disabled = true;
  }
  return menu;
}

const showLevelOptions = [
  {
    value: 1,
    label: "标准"
  },
  {
    value: 2,
    label: "专家"
  },
  {
    value: 3,
    label: "全部"
  }
];
function getLevelName(level: number) {
  return showLevelOptions.find(it => it.value === level)?.label || "";
}
</script>

<style lang="scss" scoped>
@import "@/assets/css/theme.scss";
.v-merge-property-list {
  background-color: #ffffff;
  overflow: auto;
  ._tool-bar {
    background-color: var(--md-color-sub3);
    ._type-selector {
      float: right;
      margin-right: 8px;
    }
  }
  ._head {
    > :not(:first-child) {
      background-color: $toolbar-bg-color;
    }
  }
  ._property-row {
    overflow: auto;
    &-label {
      display: flex;
    }
    &-text {
      white-space: nowrap;
    }
  }
  ._box-shadow {
    padding-left: 8px;
    box-shadow: inset 1px 0px 0px 0px #e0e0e0, inset 0px -1px 0px 0px #e0e0e0;
  }
  ._selected {
    background-color: $theme-color;
    color: #ffffff;
  }
  ._box-span {
    width: 10px;
  }
}
</style>
